package com.lance.springbootes.service;

import com.lance.springbootes.model.Goods;
import com.lance.springbootes.model.Person;
import com.lance.springbootes.repository.GoodsRepository;
import com.lance.springbootes.utils.ParseJdHtmlUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;


/**
 * @Classname GoodService
 * @Description
 * @Date 2022/2/21 13:33
 * @Author lance
 */
@Service
@Slf4j
public class GoodService {
    @Autowired
    GoodsRepository goodsRepository;
    @Autowired
    RestHighLevelClient restHighLevelClient;
    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;


    public List<Goods> addToEs(String keyword) {
        List<Goods> goods = ParseJdHtmlUtil.parseByKeyword(keyword);
        goodsRepository.saveAll(goods);
        return goods;
    }

    public Map<String, Object> getData(String keyword, int current, int size) {
        PageRequest pageRequest = PageRequest.of(current, size);
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("name", keyword);
        Page<Goods> searchPage = goodsRepository.search(matchQueryBuilder, pageRequest);
        HashMap<String, Object> map = new HashMap<>(2);
        // 分页条件
        log.info("【Goods】总条数 = {}", searchPage.getTotalElements());
        log.info("【Goods】总页数 = {}", searchPage.getTotalPages());
        map.put("total", searchPage.getTotalElements());
        map.put("data", searchPage.getContent());
        return map;
    }

    @SneakyThrows
    public Map<String, Object> getHighLightData(String keyword, int current, int size) {
        // SearchRequest searchRequest = new SearchRequest("goods");
        // SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // // 精确查询，添加查询条件
        // MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", keyword);
        // searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        // searchSourceBuilder.query(matchQueryBuilder);
        // // 分页
        // searchSourceBuilder.from(current);
        // searchSourceBuilder.size(size);
        // // 高亮 =========
        //HighlightBuilder highlightBuilder = new HighlightBuilder();
        // highlightBuilder.field("name");
        // highlightBuilder.preTags("<span style='color:red'>");
        // highlightBuilder.postTags("</span>");
        // searchSourceBuilder.highlighter(highlightBuilder);
        // // 执行查询
        // searchRequest.source(searchSourceBuilder);
        // SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // // 解析结果 ==========
        // SearchHits hits = searchResponse.getHits();
        // List<Map<String, Object>> results = new ArrayList<>();
        // for (SearchHit documentFields : hits.getHits()) {
        //     // 使用新的字段值（高亮），覆盖旧的字段值
        //     Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
        //     // 高亮字段
        //     Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
        //     HighlightField name = highlightFields.get("name");
        //     // 替换
        //     if (name != null){
        //         Text[] fragments = name.fragments();
        //         StringBuilder new_name = new StringBuilder();
        //         for (Text text : fragments) {
        //             new_name.append(text);
        //         }
        //         sourceAsMap.put("name",new_name.toString());
        //     }
        //     results.add(sourceAsMap);
        // }
        // return results;
        PageRequest pageRequest = PageRequest.of(current, size);
        // 构造查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词条件
        queryBuilder.withQuery(QueryBuilders.matchQuery("name", keyword));
        queryBuilder.withPageable(pageRequest);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        queryBuilder.withHighlightBuilder(highlightBuilder);
        NativeSearchQuery searchQuery = queryBuilder.build();
        SearchHits<Goods> goods = elasticsearchRestTemplate.search(searchQuery, Goods.class, IndexCoordinates.of("goods"));
        List<Goods> list = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>(2);
        List<SearchHit<Goods>> searchHits = goods.getSearchHits();
        for (SearchHit<Goods> searchHit : searchHits) {
           String name = searchHit.getHighlightFields().get("name").get(0);
            Goods content = searchHit.getContent();
            content.setName(name);
            list.add(content);
        }

        map.put("total",goods.getTotalHits());
        map.put("data",list);

        return map;
    }


}
